import { Feature } from "ol";
import GeoJSON from "ol/format/GeoJSON";
import LineString from "ol/geom/LineString";
import Point from "ol/geom/Point";
import routeLayer from "./layers/routeLayer";

const format = new GeoJSON();

export type RoutingStep = Feature<Point | LineString>;

export class RoutingStepArray {
  private routingSteps: Array<RoutingStep>;
  constructor(routingSteps: Array<RoutingStep>) {
    this.routingSteps = routingSteps.slice();
  }
  append(step: RoutingStep): RoutingStepArray {
    return new RoutingStepArray(this.routingSteps.concat([step]));
  }
  delete(index: number): RoutingStepArray {
    const result = this.routingSteps.slice();
    result.splice(index, 1);
    return new RoutingStepArray(result);
  }
  find(step: RoutingStep): number | undefined {
    if (step.getGeometry()?.getType() === "Point") {
      const name = step.get("名称");
      for (let i = 0; i < this.routingSteps.length; ++i) {
        const candi = this.routingSteps[i];
        if (candi.get("名称") === name) {
          return i;
        }
      }
    } else {
      const id = step.get("FID");
      for (let i = 0; i < this.routingSteps.length; ++i) {
        const candi = this.routingSteps[i];
        if (candi.get("FID") === id) {
          return i;
        }
      }
    }
  }
  public get length(): number {
    return this.routingSteps.length;
  }
  public get array(): Array<RoutingStep> {
    return this.routingSteps;
  }
  serialize(): string {
    const content = this.routingSteps
      .map((feature) => {
        return format.writeFeature(feature);
      })
      .join(",");
    return `[${content}]`;
  }
}

function deserializeGeoJSON(geoJSON: any): RoutingStep {
  const feature = format.readFeature(geoJSON);
  if (feature.getGeometry()?.getType() === "LineString") {
    const source = routeLayer.getSource();
    const origin = source.getFeatureById(feature.getId() as number);
    if (origin !== null) {
      feature.setStyle(origin.getStyle());
      source.removeFeature(origin);
      source.addFeature(feature);
    } else {
      console.error("Cannot find feature %s from %s", feature, source);
    }
  }
  return feature;
}

export function deserialize(designer: Array<any>): RoutingStepArray {
  return new RoutingStepArray(designer.map(deserializeGeoJSON));
}
